﻿using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Windows.Forms;
using ewal.Msg;
using nbb.darbo_grafikas.Properties;

namespace nbb.darbo_grafikas
{
    internal partial class FormSetupJob : Form
    {
        Darbas tmpJob;

        // kažin, ar reikalingi atskiri kintamieji - galbūt galima datasource padaryti tiesiai iš Find
        List<Meistrija> localMeistrijos;
        List<Stotis> localStotys;

        // Decimal skaičiaus parsinimui
        CultureInfo myCulture = new CultureInfo(Settings.Default.CultureName);

        // čia yra laikomi paskutiniai naudoti duomenys tam defektoskopui:
        // linija, meistrija, operatorių sąrašas
        LastUsed paskutiniai;

        // konstruktorius, kai dirbama su Darbas, kuris jau buvo sukurtas
        internal FormSetupJob(Darbas job)
        {
            InitializeComponent();

            tmpJob = job;
        }

        // konstruktorius, kai dirbama su Darbas, kurio dar nėra sukurta
        internal FormSetupJob(DateTime data, Defektoskopas defektoskopas)
        {
            InitializeComponent();
            tmpJob = new Darbas(data, defektoskopas);
        }

        private void FormSetupJob_Load(object sender, EventArgs e)
        {            
            txbData.Text = tmpJob.Data.ToShortDateString();
            txbDf.Text = tmpJob.Defektoskopas.Pavadinimas;
            
            
            cmbLinija.DataSource = Program.Linijos;
            cmbLinija.DisplayMember = "PilnasPavadinimas";
            cmbLinija.ValueMember = "Id";

            cmbMeistrija.DisplayMember = "PilnasPavadinimas";
            cmbMeistrija.ValueMember = "Id";

            cmbStotis.DisplayMember = "PilnasPavadinimas";
            cmbStotis.ValueMember = "Id";

            clbOperatoriai.DisplayMember = "VardasPavardeKodas";
            clbKitiReikalai.DisplayMember = "PavadinimasKodas";

            if (!Program.Paskutiniai.ContainsKey(tmpJob.Defektoskopas.Id)) // jeigu tokio defektoskopo dar nebuvo
            {
                paskutiniai = new LastUsed();                          
                cmbLinija.SelectedIndex = 0;
                cmbMeistrija.DataSource = meistrijosByLinijaId((int)cmbLinija.SelectedValue, Program.Meistrijos);
                cmbMeistrija.SelectedIndex = 0;
                cmbStotis.DataSource = stotysByMeistrijaLinijaId((int)cmbMeistrija.SelectedValue, (int)cmbLinija.SelectedValue, Program.Stotys);
                cmbStotis.SelectedIndex = -1;
                populateCheckBoxList<Operatorius>(clbOperatoriai, Program.Operatoriai, null);
                populateCheckBoxList<KitasReikalas>(clbKitiReikalai, Program.KitiReikalai, null);
            }
            else // jeigu defektoskopas buvo
            {
                paskutiniai = Program.Paskutiniai[tmpJob.Defektoskopas.Id];

                if (tmpJob.Id == 0) // jeigu defektoskopas buvo ir kuriamas naujas langelis
                {
                    paskutiniai = Program.Paskutiniai[tmpJob.Defektoskopas.Id];
                    setComboBoxValue(cmbLinija, paskutiniai.Linija.Id, 0);
                    cmbMeistrija.DataSource = meistrijosByLinijaId((int)cmbLinija.SelectedValue, Program.Meistrijos);
                    setComboBoxValue(cmbMeistrija, paskutiniai.Meistrija.Id, 0);
                    cmbStotis.DataSource = stotysByMeistrijaLinijaId((int)cmbMeistrija.SelectedValue, (int)cmbLinija.SelectedValue, Program.Stotys);
                    cmbStotis.SelectedIndex = -1;
                    populateCheckBoxList<Operatorius>(clbOperatoriai, Program.Operatoriai, paskutiniai.Operatoriai);
                    populateCheckBoxList<KitasReikalas>(clbKitiReikalai, Program.KitiReikalai, null);
                }
                else // jeigu defektoskopas buvo ir redaguojamas senas langelis
                {
                    paskutiniai = Program.Paskutiniai[tmpJob.Defektoskopas.Id];
                    setComboBoxValue(cmbLinija, tmpJob.Linija.Id, 0);
                    cmbMeistrija.DataSource = meistrijosByLinijaId((int)cmbLinija.SelectedValue, Program.Meistrijos);
                    setComboBoxValue(cmbMeistrija, tmpJob.Meistrija.Id, 0);
                    cmbStotis.DataSource = stotysByMeistrijaLinijaId((int)cmbMeistrija.SelectedValue, (int)cmbLinija.SelectedValue, Program.Stotys);
                    setComboBoxValue(cmbStotis, tmpJob.Stotis.Id, -1);
                    
                    populateCheckBoxList<Operatorius>(clbOperatoriai, Program.Operatoriai, tmpJob.OperatoriuSarasas);
                    populateCheckBoxList<KitasReikalas>(clbKitiReikalai, Program.KitiReikalai, tmpJob.KituReikaluSarasas);
                }
            }

            this.cmbLinija.SelectedIndexChanged += new System.EventHandler(this.cmbLinija_SelectedIndexChanged);
            this.cmbMeistrija.SelectedIndexChanged += new System.EventHandler(this.cmbMeistrija_SelectedIndexChanged);
            
        }

        private void setComboBoxValue(ComboBox cmb, int value, int indexIfSomethingWrong)
        {
            try
            {
                cmb.SelectedValue = value;
            }
            catch
            {
                cmb.SelectedIndex = indexIfSomethingWrong;
            }
        }

        private void btnOK_Click(object sender, EventArgs e)
        {
            if (!Program.Paskutiniai.ContainsKey(tmpJob.Defektoskopas.Id)) 
                Program.Paskutiniai.Add(tmpJob.Defektoskopas.Id, paskutiniai);      
            // sukuriamas naujas darbas, jeigu tokio nebuvo

            if (chbWorkOff.Checked)
            {
                tmpJob.Linija = Program.Linijos.Find(linija => linija.Id == (int)cmbLinija.SelectedValue);
                tmpJob.Meistrija = Program.Meistrijos.Find(meistrija => meistrija.Id == (int)cmbMeistrija.SelectedValue);
                tmpJob.Stotis = cmbStotis.SelectedIndex == -1 ? null : Program.Stotys.Find(stotis => stotis.Id == (int)cmbStotis.SelectedValue);
                tmpJob.NuoIki = txbKmNuoIki.Text.Trim();

                try
                { tmpJob.KmPagrKeliu = stringToDecimal(txbPagrKm.Text); }
                catch
                {
                    Msg.ErrorMsg("Nesuprantamas pagrindinio kelio kilometrų skaičius");
                    return;
                }

                try
                { tmpJob.KmKituKeliu = stringToDecimal(txbKituKm.Text); }
                catch
                {
                    Msg.ErrorMsg("Nesuprantamas kitų kelių kilometrų skaičius");
                    return;
                }

                try
                { tmpJob.VntIesmu = stringToInt(txbIesmu.Text); }
                catch
                {
                    Msg.ErrorMsg("Nesuprantamas iešmų skaičius");
                    return;
                }
            }
            else
            {
                tmpJob.Linija = null;
                tmpJob.Meistrija = null;
                tmpJob.Stotis = null;
                tmpJob.NuoIki = string.Empty;
                tmpJob.KmPagrKeliu = 0;
                tmpJob.KmKituKeliu = 0;
                tmpJob.VntIesmu = 0;
            }


            paskutiniai.Operatoriai.Clear();
            foreach (Operatorius oper in clbOperatoriai.CheckedItems)
            {
                paskutiniai.Operatoriai.Add(oper);
                tmpJob.OperatoriuSarasas.Add(oper);
            }

            foreach (KitasReikalas kr in clbKitiReikalai.CheckedItems)
                tmpJob.KituReikaluSarasas.Add(kr);

            Program.CurrentDarbas = tmpJob;
            if (tmpJob.Id == 0)
                Program.Darbai.Add(tmpJob);

            paskutiniai.Linija = Program.Linijos.Find(linija => linija.Id == (int)cmbLinija.SelectedValue);
            paskutiniai.Meistrija = Program.Meistrijos.Find(Meistrija => Meistrija.Id == (int)cmbMeistrija.SelectedValue);

            this.DialogResult = DialogResult.OK;
            this.Close();
        }

        private void cmbStotis_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Delete)
            {
                cmbStotis.SelectedIndex =-1;
            }
        }

        private void cmbLinija_SelectedIndexChanged(object sender, EventArgs e)
        {            
            int currentLinijosId;
            if (cmbLinija.SelectedIndex >= 0)
            {
                currentLinijosId = (int)cmbLinija.SelectedValue;
                localMeistrijos = Program.Meistrijos.FindAll(meistrija => meistrija.LinijosId == currentLinijosId);
            }
            else
            {
                currentLinijosId = 0;
                localMeistrijos = Program.Meistrijos;
            }

            cmbMeistrija.DataSource = localMeistrijos;
            cmbMeistrija.SelectedIndex = 0;
        }

        private void cmbMeistrija_SelectedIndexChanged(object sender, EventArgs e)
        {
            int currentMeistrijosId;
            int currentLinijosId = (int)cmbLinija.SelectedValue;
            if (cmbMeistrija.SelectedIndex >= 0)
            {
                currentMeistrijosId = (int)cmbMeistrija.SelectedValue;
                localStotys = Program.Stotys.FindAll(stotis => stotis.MeistrijosId == currentMeistrijosId &&
                                                                        stotis.LinijosId == currentLinijosId);
            }
            else
            {
                currentMeistrijosId = 0;
                localStotys = null;
            }

            cmbStotis.DataSource = localStotys;
            cmbStotis.SelectedIndex = -1;
        }

        private void populateCheckBoxList<T>(CheckedListBox clb, List<T> fullList, List<T> checkedList)
        {
            foreach (T obj in fullList)
            {
                clb.Items.Add(obj, checkedList==null ? false : checkedList.Contains<T>(obj));
            }
        }

        private List<Meistrija> meistrijosByLinijaId(int linijosId, List<Meistrija> meistrijaStorage)
        {
            return meistrijaStorage.FindAll(meistrija => meistrija.LinijosId == linijosId);
        }

        private List<Stotis> stotysByMeistrijaLinijaId(int meistrijosId, int linijosId, List<Stotis> stotysStorage)
        {
            return stotysStorage.FindAll(stotis => stotis.MeistrijosId == meistrijosId && stotis.LinijosId == linijosId);
        }

        private decimal stringToDecimal(string text)
        {
            if (string.IsNullOrWhiteSpace(text)) return 0m;
            return Decimal.Parse(text, myCulture);
        }

        private int stringToInt(string text)
        {
            if (string.IsNullOrWhiteSpace(text)) return 0;
            return Int32.Parse(text, myCulture);
        }
        
        private void btnClear_Click(object sender, EventArgs e)
        {

        }

        private void chbWorkOff_CheckedChanged(object sender, EventArgs e)
        {
            pnWork.Enabled = chbWorkOff.Checked;
        }
    }
}
